package org.university.controller;

import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.university.common.ApiResponse;
import org.university.entity.Enrollment;
import org.university.entity.TeachingClass;
import org.university.repository.EnrollmentRepository;
import org.university.repository.TeachingClassRepository;
import org.university.service.EnrollmentService;
import org.university.service.impl.EnrollmentServiceImpl;

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

/**
 * 选课
 */
@RestController
@RequestMapping("/enrollments")
public class EnrollmentController {

    private final EnrollmentService enrollmentService;
    private final EnrollmentServiceImpl enrollmentServiceImpl;
    private final EnrollmentRepository enrollmentRepository;
    private final TeachingClassRepository teachingClassRepository;

    public EnrollmentController(EnrollmentService enrollmentService, EnrollmentServiceImpl enrollmentServiceImpl, EnrollmentRepository enrollmentRepository, TeachingClassRepository teachingClassRepository) {
        this.enrollmentService = enrollmentService;
        this.enrollmentServiceImpl = enrollmentServiceImpl;
        this.enrollmentRepository = enrollmentRepository;
        this.teachingClassRepository = teachingClassRepository;
    }

    /**
     * 获取所有选课记录
     *
     * @return
     */
    @GetMapping
    public Page<Enrollment> getAllEnrollments() {
        // todo 增加分页查询
        return enrollmentService.findAll();
    }

    /**
     * 根据选课id获取记录
     *
     * @param id 选课id
     * @return
     */
    @GetMapping("/{id}")
    public ResponseEntity<Enrollment> getEnrollmentById(@PathVariable Integer id) {
        Optional<Enrollment> enrollment = enrollmentService.findById(id);
        return enrollment.map(ResponseEntity::ok)
                .orElseGet(() -> ResponseEntity.notFound().build());
    }

    /**
     * 根据学生id获取选课记录
     *
     * @param studentId 学生id
     * @return
     */
    @GetMapping("/student/{studentId}")
    public List<Enrollment> getEnrollmentsByStudentId(@PathVariable String studentId) {
        // return enrollmentService.findByStudentId(studentId);
        throw new RuntimeException("未实现");
    }

    /**
     * 根据课程id获取选课记录
     *
     * @param classId
     * @return
     */
    @GetMapping("/class/{classId}")
    public List<Enrollment> getEnrollmentsByClassId(@PathVariable String classId) {
        // return enrollmentService.findByClassId(classId);
        throw new RuntimeException("未实现");
    }

    /**
     * 新建选课
     *
     * @param enrollment
     * @return
     */
    @PostMapping
    public ResponseEntity<Enrollment> createEnrollment(@RequestBody Enrollment enrollment) {
        Enrollment savedEnrollment = enrollmentService.save(enrollment);
        return new ResponseEntity<>(savedEnrollment, HttpStatus.CREATED);
    }

    /**
     * 新建学生选课
     *
     * @param studentId
     * @param classId
     * @return
     */
    @PostMapping("/enroll")
    public ResponseEntity<Enrollment> enrollStudent(@RequestParam String studentId, @RequestParam Integer classId) {
        try {
            Enrollment enrollment = enrollmentService.enrollStudent(studentId, classId);
            return new ResponseEntity<>(enrollment, HttpStatus.CREATED);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(null);
        }
    }

    /**
     * 根据选课id退课
     *
     */
    @PostMapping("/drop/{studentId}/{courseId}")
    public ResponseEntity<ApiResponse<Enrollment>> dropCourse(@PathVariable String studentId, @PathVariable String courseId) {
         /*根据学生id和课程id获取enrollment表对应的数据*/
        // 使用Optional避免空指针
        Optional<Enrollment> enrollmentOpt = Optional.ofNullable(enrollmentRepository
                .findByStudentIdAndCourseId(studentId, courseId));

        // 没有找到匹配数据
        if (enrollmentOpt.isEmpty()) {
            return ApiResponse.error(HttpStatus.NOT_FOUND, "退课失败，没有选课对应的记录");
        }

        /*软删除*/
        // 调用delete()将自动触发@SQLDelete的SQL
        enrollmentRepository.delete(enrollmentOpt.get());

        /*对应教学班人数减一*/
        TeachingClass teachingClass = enrollmentOpt.get().getTeachingClass();
        teachingClass.decreaseStudentCount();
        teachingClassRepository.save(teachingClass);

        // 返回成功信息
        return ApiResponse.success(enrollmentOpt.get());
    }

    /**
     * 根据选课id更新选课记录
     *
     * @param id
     * @param enrollment
     * @return
     */
    @PutMapping("/{id}")
    public ResponseEntity<Enrollment> updateEnrollment(@PathVariable Integer id, @RequestBody Enrollment enrollment) {
        if (!enrollmentService.findById(id).isPresent()) {
            return ResponseEntity.notFound().build();
        }
        enrollment.setEnrollmentId(id);
        Enrollment updatedEnrollment = enrollmentService.save(enrollment);
        return ResponseEntity.ok(updatedEnrollment);
    }

    /**
     * 根据选课id删除选课记录
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteEnrollment(@PathVariable Integer id) {
        if (!enrollmentService.findById(id).isPresent()) {
            return ResponseEntity.notFound().build();
        }
        enrollmentService.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    /**
     * 学生选课
     * @param studentId 学生号
     * @param courseId 课程号
     * @return 选课记录
     */
    @PostMapping("/selectCourse/{studentId}/{courseId}")
    public ResponseEntity<ApiResponse<Enrollment>> selectCourse(
            @PathVariable String studentId,
            @PathVariable String courseId
    ) {
        return enrollmentServiceImpl.selectCourse(studentId, courseId);
    }

    /**
     * 资源不存在错误处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(NoSuchElementException.class)
    public ResponseEntity<String> handleNoSuchElementException(NoSuchElementException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    }

    /**
     * 请求失败错误处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }
}
